package com.dropdb.demo.controller.admin;

import com.dropdb.demo.bean.Storage;
import com.dropdb.demo.bean.bo.BaseData;
import com.dropdb.demo.bean.vo.BaseRespVO;
import com.dropdb.demo.service.StorageService;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

@RestController
@RequestMapping("admin/storage")
@Validated
public class AdminStorageController {
    @Value("${mall.upload-path}")
    private String fileUpLoadPath;

    @Autowired
    StorageService storageService;

    /**
     * 文件上传
     * @return 返回储存信息
     */
    @RequestMapping(value = "create", method = RequestMethod.POST)
    @RequiresPermissions(value = {"*", "admin:storage:create"}, logical = Logical.OR)
    public BaseRespVO fileUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        // 如果文件为空
        if (file.isEmpty()) return BaseRespVO.error(1000, "文件为空");
        //获取小类型
        String type = file.getContentType();
        int i = type.indexOf("/");
        if (i != -1) {
            type = type.substring(i + 1);
        }
        // 文件唯一标识
        String key = UUID.randomUUID() + "." + type;
        // 通过hashcode散列文件，创建目录，已解决同一目录下文件过多的问题
        int hash = key.hashCode();
        // 以十六进制无符号整数形式返回一个整数参数的字符串表示形式
        String hexString = Integer.toHexString(hash);
        char[] chars = hexString.toCharArray();
        String upload_prefix = "";
        for (char c : chars) {
            //文件目录的创建
            upload_prefix = upload_prefix + "/" + c;
        }
        String relativePath = upload_prefix + "/" + key;
        String realPath = fileUpLoadPath + relativePath;
        //使用当前应用目录，会出现问题，springboot内置tomcat每次重新部署都会生成一个temp
        //String realPath = request.getServletContext().getRealPath(relativePath);
        //放到项目classpath目录下
        /*String realPath = null;
        try {
            realPath = ResourceUtils.getURL("classpath:").getPath() + relativePath;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return BaseRespVO.error(1000, "上传失败");
        }*/
        // 目标目录
        File desfile = new File(realPath);
        //如果父级目录不存在
        if (!desfile.getParentFile().exists()) {
            desfile.getParentFile().mkdirs();
        }
        try {
            file.transferTo(desfile);
        } catch (IOException e) {
            e.printStackTrace();
            return BaseRespVO.error(1000, "上传失败");
        }
        //避免出现0:0:0:0:0:0:0:1
        String localAddr = request.getLocalAddr();
        if ("0:0:0:0:0:0:0:1".equals(localAddr)) localAddr = "localhost";
        String url = "http://" + localAddr + ":" + request.getLocalPort() + "/" + relativePath;
        //插入
        Storage storage = storageService.insertStorageFile(file, key, url);
        Integer id = storage.getId();
        storage.setId(id);
        return BaseRespVO.ok(storage);
    }

    @GetMapping("list")
    @RequiresPermissions(value = {"*", "admin:storage:list"}, logical = Logical.OR)
    public BaseRespVO list(@Min(value = 1, message = "页数不能小于1") Integer page,
                           @Min(value = 1, message = "条数不能小于1") Integer limit,
                           String key,
                           String name,
                           @NotBlank(message = "参数非法") String sort,
                           @NotBlank(message = "参数非法") String order) {
        BaseData<Storage> data = storageService.list(page, limit, key, name, sort, order);
        return BaseRespVO.ok(data);
    }

    @PostMapping("update")
    @RequiresPermissions(value = {"*", "admin:storage:update"}, logical = Logical.OR)
    public BaseRespVO update(@RequestBody Storage storage) {
        Storage fromDB = storageService.update(storage);
        return null != fromDB ? BaseRespVO.ok(fromDB) : BaseRespVO.error(502, "系统内部错误");
    }

    @PostMapping("delete")
    @RequiresPermissions(value = {"*", "admin:storage:delete"}, logical = Logical.OR)
    public BaseRespVO delete(@RequestBody Storage storage) {
        int i = storageService.delete(storage);
        return 1 == i ? BaseRespVO.ok() : BaseRespVO.error(502, "系统内部错误");
    }

}
